package com.mspbots.core.wise.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mspbots.core.AbstractBaseServiceImpl;
import com.mspbots.core.system.mapper.SystemConfigurationMapper;
import com.mspbots.core.system.model.SystemConfiguration;
import com.mspbots.core.wise.mapper.TenantConfigurationMapper;
import com.mspbots.core.wise.model.TenantConfiguration;
import com.mspbots.core.wise.service.TenantConfigurationService;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

import static com.mspbots.core.wise.controller.TenantRuleController.REDIS_KEY_PREFIX_TENANT;

/**
 * @author billb
 */
@Service
public class TenantConfigurationServiceImpl extends AbstractBaseServiceImpl<TenantConfigurationMapper, TenantConfiguration>
        implements TenantConfigurationService {

    private final StringRedisTemplate stringRedisTemplate;
    private final SystemConfigurationMapper systemConfigurationMapper;

    public TenantConfigurationServiceImpl(StringRedisTemplate stringRedisTemplate,
                                          SystemConfigurationMapper systemConfigurationMapper) {
        this.stringRedisTemplate = stringRedisTemplate;
        this.systemConfigurationMapper = systemConfigurationMapper;
    }

    @Override
    public List<TenantConfiguration> list(Wrapper<TenantConfiguration> queryWrapper) {
        return super.list(queryWrapper);
    }

    @Override
    public TenantConfiguration selectByKeyword(long tenantId, String keyword) {
        QueryWrapper<TenantConfiguration> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("tenant_id", tenantId);
        queryWrapper.eq("keyword", keyword);
        return this.baseMapper.selectOne(queryWrapper);
    }

    /**
     * will get all configurations based on keyword
     * will ignore tenant_id
     *
     * @param keyword
     * @return
     */
    @Override
    public List<TenantConfiguration> selectListByKeyword(String keyword) {
        QueryWrapper<TenantConfiguration> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("keyword", keyword);
        return this.baseMapper.selectList(queryWrapper);
    }

    @Override
    public Collection<TenantConfiguration> selectAllByTenantId(long tenantId) {

        List<SystemConfiguration> sysConfigurations = systemConfigurationMapper.selectList(null);

        QueryWrapper<TenantConfiguration> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("tenant_id", tenantId);
        Collection<TenantConfiguration> tenantConfigurations = this.baseMapper.selectList(queryWrapper);

        if (sysConfigurations != null && sysConfigurations.size() > 0) {
            Collection<TenantConfiguration> needCombined = new ArrayList<>();

            for (SystemConfiguration sc : sysConfigurations) {
                boolean exists = false;
                for (TenantConfiguration tc : tenantConfigurations) {
                    if (sc.getKeyword().equalsIgnoreCase(tc.getKeyword())) {
                        exists = true;
                        break;
                    }
                }
                if (!exists) {
                    TenantConfiguration newtc = new TenantConfiguration();
                    newtc.setKeyword(sc.getKeyword());
                    newtc.setKeywordValue(sc.getKeywordValue());
                    newtc.setCreateDate(sc.getCreateDate());
                    newtc.setTenantId(tenantId);
                    newtc.setId(0L);

                    needCombined.add(newtc);
                }
            }
            tenantConfigurations.addAll(needCombined);
        }

        return tenantConfigurations;
    }

    @Override
    public List<TenantConfiguration> batchSave(List<TenantConfiguration> tenantConfigurations) {
        List<TenantConfiguration> list = tenantConfigurations.parallelStream().peek(newConfiguration -> {
            QueryWrapper<TenantConfiguration> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("tenant_id", newConfiguration.getTenantId());
            queryWrapper.eq("keyword", newConfiguration.getKeyword());
            TenantConfiguration configuration = this.baseMapper.selectOne(queryWrapper);
            if (ObjectUtils.isEmpty(configuration)) {
                this.baseMapper.insert(newConfiguration);
            } else {
                newConfiguration.setId(configuration.getId());
                newConfiguration.setCreateDate(configuration.getCreateDate());
                this.baseMapper.updateById(newConfiguration);
            }
        }).collect(Collectors.toList());
        for (TenantConfiguration tenantConfiguration : list) {
            stringRedisTemplate.opsForValue().set(REDIS_KEY_PREFIX_TENANT + tenantConfiguration.getTenantId() + ":" + tenantConfiguration.getKeyword(), tenantConfiguration.getKeywordValue());
        }

        return list;
    }


}
